/*	Project temp_hume_serial02
	PIC16F877
*/
#include <pic.h>
__CONFIG(
	  PWRTEN
	& BORDIS
	& UNPROTECT
	& WDTDIS
	& LVPDIS
	& HS
	);
__IDLOC(F877);
#define E RB6
#define XON 17
#define XOFF 19
unsigned char xf;
unsigned char rbuf[16];
unsigned char wp;
unsigned char rp;
unsigned char dc;
void lcd_w_com4(unsigned char d){
	PORTB = d & 0x0f;
	E = 1; NOP();
	E = 0;
}
void lcd_w_chr4(unsigned char d){
	PORTB = (d & 0x0f) | 0x10;
	E = 1; NOP();
	E = 0;
}
void lcd_bfck(void){
	unsigned char d;
	PORTB = 0;
	TRISB3 = 1;
	PORTB = 0b00100000;
	do{
		E = 1; NOP();
		d = RB3;
		E = 0;
		NOP(); NOP();
		E = 1; NOP();
		E = 0;
		NOP(); NOP();
	} while(d);
	PORTB = 0;
	TRISB3 = 0;
}
void lcd_putcom(unsigned char d){
	lcd_bfck();
	lcd_w_com4(d >> 4);
	lcd_w_com4(d);
}
void lcd_locate(
unsigned char x, unsigned char y){
	lcd_putcom((x + 0x40 * y) | 0x80);
}
void lcd_putchr(unsigned char d){
	lcd_bfck();
	lcd_w_chr4(d >> 4);
	lcd_w_chr4(d);
}
void lcd_puts(const unsigned char *s){
	while(*s) lcd_putchr(*s++);
}
unsigned int bresenham(
    unsigned int n,unsigned int m,unsigned int d
){
    unsigned int e;
    unsigned int s;
    s = e = 0;
    while(n--){
        e += m;
        while(e >= d){
             e -= d;
             s++;
       }
   }
   return s;
}
void lcd_putT(unsigned int v){
	unsigned char i;
	unsigned char buf[4];
    v = bresenham(v - 116,518,10);
	for(i = 0; i < 4; i++)
		buf[i] = '0';
	i = 3;
	do {
		buf[i] = (v % 10) + '0';
		v = v / 10;
		i--;
	} while(v > 0);
	if(buf[0] > 0) lcd_putchr(buf[0]);
    else lcd_putchr(' ');
	lcd_putchr(buf[1]);
	lcd_putchr('.');
	lcd_putchr(buf[2]);
	lcd_puts("C");
}
void lcd_putH(unsigned int v){
	unsigned char i;
	unsigned char buf[4];
	v = bresenham(v - 3,197,10);
	for(i = 0; i < 4; i++)
		buf[i] = '0';
	i = 3;
	do {
		buf[i] = (v % 10) + '0';
		v = v / 10;
		i--;
	} while(v > 0);
	if(buf[0] > 0) lcd_putchr(buf[0]);
    else lcd_putchr(' ');
    lcd_putchr(buf[1]);
	lcd_putchr('.');
	lcd_putchr(buf[2]);
	lcd_puts("%");
}
void interrupt entry(void){
	unsigned char c;
	if(RCIF){
		c = RCREG;
		if(c == XON || c == XOFF){
			xf = c;
			return;
		}
		if(dc == 16) return;
		rbuf[wp] = c;
		wp++;
		wp &= 15;
		dc++;
		if(dc == 12){
			while(TXIF == 0);
			TXREG = XOFF;
		}
	}
}
unsigned char getchr(void){
	unsigned char c;
	while(dc == 0);
	RCIE = 0;
	c = rbuf[rp];
	rp++;
	rp &= 15;
	dc --;
	if(dc == 12){
		while(TXIF == 0);
		TXREG = XON;
	}
	RCIE = 1;
	return(c);
}
void putchr(unsigned char c){
    while(xf == XOFF);
    while(TXIF == 0);
    TXREG = c;
}
void put(const unsigned char *s){
	while(*s) putchr(*s++);
}
void putui(
    unsigned int ui, unsigned char d){
	unsigned char i;
	unsigned char buf[5];
	for(i = 0; i < 5; i++)
		buf[i] = ' ';
	i = 4;
	do {
		buf[i] = (ui % 10) + '0';
		ui = ui / 10;
		i--;
	} while(ui > 0);
	for(i = (5 - d); i < 5; i++)
			putchr(buf[i]);
}
void putui_dot(unsigned int v){
	unsigned char i;
	unsigned char buf[4];
	for(i = 0; i < 4; i++)
		buf[i] = '0';
	i = 3;
	do {
		buf[i] = (v % 10) + '0';
		v = v / 10;
		i--;
	} while(v > 0);
	if(buf[0] > 0) putchr(buf[0]);
    else putchr(' ');
    putchr(buf[1]);
	putchr('.');
	putchr(buf[2]);
	}
void main(void){
	unsigned int v;
	unsigned int v0, v1;
	OPTION = 0b10000111; // 1/256
	PORTB = 0;
	TRISB =  0b10000000;
	ADCON1 = 0b10000100;
	ADCON0 = 0b10000001;
	PORTA = 0;
	TRISA =  0b00001011;
	PORTC = 0;
	TRISC = 0b10000000;
    //CCP for PWM
    PR2 = 153; // 1kHz
    T2CON = 0b00000110; // TMR2 1/16
    CCPR1L = 75;
    CCP1CON = 0b00001100;
    //sci
	SPBRG = 128;
	TXSTA = 0b00100100;
	RCSTA = 0b10010000;
	wp = 0;
	rp = 0;
	dc = 0;
	xf = XON;
	RCIE = 1;
	PEIE = 1;
	ei();
	TMR0 = 0; while(TMR0 < 255);
	lcd_w_com4(0x03);
	TMR0 = 0; while(TMR0 < 80);
	lcd_w_com4(0x03);
	TMR0 = 0; while(TMR0 < 2);
	lcd_w_com4(0x03);
	TMR0 = 0; while(TMR0 < 2);
	lcd_w_com4(0x02);
	lcd_putcom(0x28);
	lcd_putcom(0x01);
	lcd_putcom(0x0c);
	lcd_puts("TEMP   HUME");
    put("\n");
    put("  time(s) ");
    put(" Temp(c)");
    put("  Hume(%)");
    put("\n");
    put("\n");
    unsigned int k, k0;
        k = 0;
        k0 = 0;
    while(1){
        k = k + 1;
        k0 = k * 10;
        put("  ");    
        putui(k0,5);
	unsigned char j;
        for(j = 0; j < 15; j++){
		//Channel 0
		ADCON0 = 0b10000001;
		TMR0 = 0;  while(TMR0 < 100);
		GODONE = 1;
		while(GODONE);
v = (ADRESH * 256) + ADRESL;
		if(v != v0){
			v0 = v;
			lcd_locate(0, 1);
			lcd_putT(v0);
		}
		//Cannel 1
		ADCON0 = 0b10001001;
		TMR0 = 0; while(TMR0 < 100);
		GODONE = 1;
		while(GODONE);
v = (ADRESH * 256) + ADRESL;
		if(v != v1){
			v1 = v;
			lcd_locate(7, 1);
			lcd_putH(v1);
        }      
	unsigned char i;
        for(i = 0; i < 25; i++){
        TMR0 = 0;
        while(TMR0 < 234);
        } 
     }
    v0 = bresenham(v0 - 116,518,10);
    put("     ");
    putui_dot(v0);
    put("      ");
    v1 = bresenham(v1 - 3,197,10);    
    putui_dot(v1);
    put("\n");
	}
   
 }